package info.pinlab.pinplayer.model.response;


import info.pinlab.pinplayer.model.task.TaskInstance;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.log4j.Logger;


public class ResponseSet {
	public static final Logger logger = Logger.getLogger(ResponseSet.class);
	private final ConcurrentHashMap<Integer, List<ResponseInstance>> responses ;
	
	private final String sessionId;
	
	public ResponseSet(String sessionId){
		this.sessionId = sessionId;
		responses = new ConcurrentHashMap<Integer, List<ResponseInstance>>();
	}

	
	public boolean hasResponse(int taskIx){
		if(!responses.keySet().contains(taskIx))
			return false;
		for (ResponseInstance respi : responses.get(taskIx)){
			if (respi!=null  && !(respi.getResponseContent() instanceof ResponseContentEmpty))
				return true;
		}
		return false;
	}
	
	public synchronized  void add(ResponseInstance r){
		final int taskIx = r.getTaskIx();
		logger.debug("Registering response " + taskIx + "." + r.getAttemptN() + " #" + r.getResponseContent().getClass().getSimpleName());
		List<ResponseInstance> respForTask = responses.get(taskIx);
		if(respForTask==null){
			respForTask = Collections.synchronizedList(new ArrayList<ResponseInstance>());
			responses.put(taskIx, respForTask);
		}
		final int respIx = r.getAttemptN();
		for(int i = 0; i<=respIx; i++){
			if(respForTask.size()<=i)
				respForTask.add(null);
		}
		respForTask.add(respIx, r);
	}

	
	public String getSessionId(){
		return sessionId;
	}
	
	/**
	 * 
	 * Wrapper for {@link #getLastRespFor()} 
	 * 
	 * @param taski
	 * @return the last non-null response item.
	 */
	public ResponseInstance getLastRespFor(TaskInstance taski){
		return getLastRespFor(taski.getTaskIx());
	}
	
	/**
	 * 
	 * @param taskIx
	 * @param skipEmptyResponse if return value can contain empty response content
	 * @return the last non-null response item.
	 */
	synchronized public ResponseInstance getLastRespFor(int taskIx){
		List<ResponseInstance> respis = responses.get(taskIx);
		ResponseInstance respi = null;
		for(int i = respis.size()-1; i >= 0 ; i--){
			respi = respis.get(i);
			if (respi == null)
				continue;
//			if (  !skipEmptyResponse &&  
//			    (  respi.getResponseContent() instanceof ResponseContentEmpty)){ //-- skip empty
//				continue;
//			}
			//-- not null, not empty --//
			break;
		}
		return respi;
	}

	public List<ResponseInstance> getAllRespsFor(TaskInstance taski){
		return getAllRespsFor(taski.getTaskIx());
	}
	public List<ResponseInstance> getAllRespsFor(int taskIx){
		List<ResponseInstance> respis = responses.get(taskIx);
		if (respis==null)
			return null;
		List<ResponseInstance> copy = new ArrayList<ResponseInstance>();
		for(ResponseInstance r : respis)
			copy.add(r);
		return copy;
	}

	
	
	
//	public List<ResponseToken> getResponsesFor(TaskToken tasktok){
//		List<ResponseToken> returnList = new ArrayList<ResponseToken>();
//		for(int i = 0; i < responses.size() ; i++){
//			ResponseToken token = responses.get(i);
//			if (token.getTaskIx() != tasktok.getTaskIx())
//				continue;
//			if (token.getTaskSetHash() != tasktok.getTaskSetHash())
//				continue;
//			if (token.getSessionId().equals(tasktok.getSessionId()))
//				continue;
//			returnList.add(token);
//		}
//		return returnList;
//	}
	
	
//	public List<ResponseToken> getResponsesFor(TaskInstance taski){
//		List<ResponseToken> returnList = new ArrayList<ResponseToken>();
//		for(int i = 0; i < responses.size() ; i++){
//			ResponseToken token = responses.get(i);
//			if (token.getTaskIx() != taski.getTaskIx())
//				continue;
//			if (token.getTaskSetHash() != taski.getTaskSetHash())
//				continue;
//			returnList.add(token);
//		}
//		return returnList;
//	}
	
}


